 \chapter*{Jot}
  

 1го февраля 2003го года я оконфузился.
  

 Чувствовал я себя в этом процессе очень глупо, не
    очень уютно и вообще как-то некомфортно. Эту историю я ещё никому
    не рассказывал, потому что немного стыдно до сих пор. По прошествии
    нескольких лет я потихоньку начинаю понимать, что всё было не так
    уж и плохо и зря я так серьёзно отношусь ко всяким мелким
    происшествиям, тем более, что стыдиться-то собственно и нечего -
    но, как говорится в бородатом анекдоте – ложки-то нашлись, а осадок
    остался.
  

 И, чтобы выветрить осадок, для излития души я
    решил, что выбирать стоит только между мегафоном на набитой народом
    площади и книгой по Maya. Сами видите, что я выбрал.
  

 1го февраля 2003го года школа Реалтайм проводила в
    Москве очередной семинар по компьютерной графике ViAGra (Visual Art
    and Graphics). На этом семинаре у меня было небольшое выступление
    на тему “Нефотореалистичный рендеринг”. Следует отметить, что я уже
    давно интересуюсь этой темой и экспериментирую с различными NPR
    техниками, используя в своей работе Renderman-совместимые рендереры
    (а в последнее время и Gelato) как источники информации для
    собственных программ и алгоритмов. И для своего выступления на
    Виагре я подготовил не только доклад, но и небольшой показ своих
    собственных достижений, которыми (втайне) очень
    гордился.
  

 А вот в конце доклада я в качестве обзора вставил в
    презентацию несколько картинок, показывающих различные
    нефотореалистичные техники рендеринга, имитирующие анимационную
    закраску, псевдоживопись, чертёжные линии, гуашь с акварелью и
    прочие интересности.
  

 Одна из этих картинок была результатом рендеринга в
    Jot.
  

 В те времена этот университетский проект ещё не
    назывался Jot, не был выложен в публичный доступ и не обрёл свою
    микроармию поклонников. Но уже тогда по рукам интересующихся
    бродила видеозапись, демонстрирующая все возможности Jot’а в
    действии.
  

 Честно вам скажу – я не помню, откуда в моей
    демонстрации взялся этот файл с видео. Возможно, я сам его привёз.
    Вполне может быть, что кто-то подошёл и поставил свой диск – я
    просто не помню.
  

 Единственное, что я вообще помню сейчас про эти 3
    минуты, пока на экране шёл показ прототипа Jot – это охи и ахи со
    всех сторон, голос девушки из середины зала, которая застонала
    “дайте мне это, я хочу делать это!” и возглас “Ну вот, это же
    гораздо круче того, что вы показывали”.
  

 Вот эта последняя фраза меня и доконала. Надеюсь,
    никто этого не заметил – но я сильно расстроился. Немного смешно
    вспоминать это сейчас, честное слово – но это так.
  

 Прошло время. Контур и заливку сейчас рендерят все,
    кому не лень – он есть в стандартной поставке Maya, он есть во
    многих рендерерах (в том числе и Renderman-совместимых) в качестве
    дополнительной опции. Студия Disney на одной из последних выставок
    Siggraph показала свой внутренний рендерер Inka, рассказала
    принципы его работы и внутреннего устройства – и с тех пор только
    очень ленивый студент не написал идеальный картунный движок.
    Проблема исчезла сама собой, вместе с ней ушла эйфория увлечения
    нерешёнными задачами и новыми технологиями, наступила пора готовых
    решений. Но даже сейчас, когда я запускаю Jot, внутри меня
    начинается какое-то противоречивое шевеление. Я продолжаю
    восторгаться его возможностями, ужасаться корявости его интерфейса,
    и я вспоминаю тот февральский день, когда весь зал ахал и охал,
    пусть и не от моих картинок.
  

 Я отлично понимаю, отчего все они так реагировали.
    Университетский проект, результат долгих лет исследований студентов
    и профессоров, Jot – классический нефотореалистичный рендерер “как
    в мультфильме” с возможностью работы из командной строки, простым
    форматом файла и изюминкой – интерактивным редактором стилей
    закраски. Интерфейс этого интерактивного редактора ужасен, но стиль
    его работы и – самое главное – результаты его работы завораживают.
    Именно поэтому в качестве второго претендента на обзор в этой главе
    я избрал Jot – хороший пример того, как пристыковать к Майке
    посторонний специализированный рендерер.
  

 Скачайте и установите Jot с сайта http://jot.cs.princeton.edu/.
    Настройка продукта – процесс достаточно сумбурный, но если вы
    внимательно прочитаете документацию и всякие там README – доступный
    и быстрый, поэтому здесь не задокументированный. Нам же интересно –
    как вывести наши данные, чтобы их понял Jot.
  

 Смотрим в исходный файл одного из
    примеров:
  

 vertices           { {{4.984928608 -4.984928608 -7.771561172e-016} ….
  

 faces    { {{160 1 161 }{78 2 79 }{44 4 45 }{26 7 27 }{17 8 19 }…
  

 То есть сцена в формате JOT описывается в виде
    точек (вершин), из которых затем собираются треугольники. Ничего
    военного, очень похоже на формат файла Wavefront OBJ – и похоже,
    что кроме этой геометрии, нас в файле ничего не интересует. Засучив
    рукава, быстренько пишем небольшой скрипт на Mel для экспорта
    данных в нужный формат (текст скрипта любезно предоставлен Егором
    Чащиным и Сергеем Цыпцыным):
  
\begin{lstlisting}[frame=single, framerule=0pt, framesep=10pt, xleftmargin=10pt, xrightmargin=10pt]
global proc export_jot(string $_filename)
{
       string $list[] = `ls -sl`;
       string $item;
       for($item in $list)
       {
             select -hi -r ($item);
             string $hi[] = `ls -sl`;
             string $it;
             print ("EXPORTING:\n");
             string $filename = $_filename;
             int $FP = fopen($filename, "w");
             for($it in $hi)
             {
                   string $type = `nodeType ($it)`;
                   if($type == "mesh")
                   {                                       
                        fprint $FP "#jot\n\nTEXBODY \t{\n";
                        fprint $FP ("\tname \t"+$item+"."+""+$it+"(celia) \n");
                        // code for WTM
                        fprint $FP "\txform \t{{1 0 0 0 }{0 1 0 0 }{0 0 1 0 }{0 0 0 1}}\n";
                          fprint $FP "\tmesh_data      { \n\t\tLMESH     {\n";
                        fprint $FP "\t\t\tvertices   { {";
                        int $nv[] = `polyEvaluate -v $it`;
                        int $nf[] = `polyEvaluate -f $it`;
                        int $ii,$jj;
                        string $varr="";
                        for($ii=0;$ii<$nv[0];$ii++)
                        {
                              float $vt[] = `xform -q -ws -t ($it+".vtx["+$ii+"]")`;
                              $varr+="{"+$vt[0]+ " "+$vt[1]+ " "+$vt[2]+ "}";
                        }
                        fprint $FP ($varr);
                        fprint $FP "}} \n";                     
                        fprint $FP "\t\t\tfaces \t{ {";
                        string $farr="";
                        for($ii=0;$ii<$nf[0];$ii++)
                        {
                              string $face[] = `polyInfo -fv ($it+".f["+$ii+"]")`;
                              string $buf[];
                              int $nn=tokenize($face[0], " ", $buf);
                              $farr+="{";
                              for($jj=2; $jj<$nn-1; $jj++) $farr+= $buf[$jj]+" ";
                              $farr+="}";
                        }
                        fprint $FP ($farr);   
                        fprint $FP "}} \n";
                        fprint $FP "\t\t\t} } \n\t} \nCREATE \t{ ";
                        fprint $FP ($item+"."+$it+"(celia)\n\t} ");                    
                    }
             }
             fclose($FP);     
       }
 }
\end{lstlisting}
  

 Как видно из текста скрипта, чтобы не
    заморачиваться с триангуляцией сцены, мы будем выводить
    исключительно полигональные объекты – помните об этом. Тэээкс, где
    там наша многострадальная овечка? Создаём новую сцену, импортируем
    овцу. Чтобы не очень много ждать в процессе экспорта, оставляем от
    бедного животного одну голову, переводим в сабдивы, а затем сразу
    же переводим в обратно в полигоны – Modify => Convert =>
    Subdiv to polygon. Объявляем в Maya наш скрипт, вызываем его на
    выполнение командой в Script Editor:
  

 export\_jot("sheep.jot");
  

 и получаем файл sheep.jot. Всё, что нам осталось
    сделать – запустить jot и насладиться результатом:
  

 \gr{image079}
  

 Как говорится в только что придуманой мной
    поговорке – овечья голова это ещё не вся овца. Что не даёт нам
    экспортировать всю модель? Излишняя медлительность скрипта, который
    вынужден обходить три с половиной тысячи вертексов. Такова природа
    вещей – писать скрипты на Mel’е легко и весело, а выполнять тяжело
    и грустно,  поскольку
    они интерпретируются, и выполняются  заведомо медленнее
    откомпилированного оптимизированного кода на C++ - и потому для
    экспорта больших и сложных моделей годятся с большой натяжкой. Дело
    мастера боится – закатываем рукава и пишем плагин, который будет
    делать всё то же самое, что и наш замечательный скрипт, но в
    десятки раз быстрее. Если с программированием на C++ и
    использованием Maya API у вас туговато – используем план Б и
    загружаем с диска готовый плагин (в качестве приглашённого
    программиста выступил Вячеслав Богданов). Для совсем ленивых я
    записал на диск полностью готовую к экспорту сцену – sheep\_jot.ma.
    Нам же осталось только привести готовую картинку:
  

 \gr{image081}
  

 Для продвинутых и
    неленивых: Пара советов.
    Обращайте внимание на то, куда смотрят нормали вашей поверхности. И
    помните о том, что при помощи приведённого выше
    Mel-скрипта  мы можем
    экспортировать в Jot только один объект – поэтому не забывайте
    объединять все полигоны в сцене в единый объект перед
    экспортом.
